home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / hurd / hurdfault.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-04  |  4.3 KB  |  143 lines

  1. /* Handle faults in the signal thread.
  2. Copyright (C) 1994 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <hurd.h>
  21. #include <hurd/signal.h>
  22. #include "hurdfault.h"
  23. #include <errno.h>
  24. #include <string.h>
  25. #include <setjmp.h>
  26. #include <stdio.h>
  27. #include "thread_state.h"
  28. #include "faultexc.h"        /* mig-generated header for our exc server.  */
  29.  
  30. jmp_buf _hurdsig_fault_env;
  31.  
  32. static mach_port_t forward_sigexc;
  33.  
  34. int _hurdsig_fault_expect_signo;
  35. int _hurdsig_fault_sigcode;
  36. int _hurdsig_fault_sigerror;
  37.  
  38. kern_return_t
  39. _hurdsig_fault_catch_exception_raise (mach_port_t port,
  40.                       thread_t thread,
  41.                       task_t task,
  42.                       int exception,
  43.                       int code,
  44.                       int subcode)
  45. {
  46.   int signo;
  47.  
  48.   if (port != forward_sigexc ||
  49.       thread != _hurd_msgport_thread || task != __mach_task_self ())
  50.     return EPERM;        /* Strange bogosity.  */
  51.  
  52.   /* Call the machine-dependent function to translate the Mach exception
  53.      codes into a signal number and subcode.  */
  54.   _hurd_exception2signal (exception, code, subcode, &signo,
  55.               &_hurdsig_fault_sigcode, &_hurdsig_fault_sigerror);
  56.  
  57.   return signo == _hurdsig_fault_expect_signo ? 0 : EGREGIOUS;
  58. }
  59.  
  60. static void
  61. faulted (void)
  62. {
  63.   struct
  64.     {
  65.       mach_msg_header_t head;
  66.       char buf[64];
  67.     } request;
  68.   struct
  69.     {
  70.       mach_msg_header_t head;
  71.       mach_msg_type_t type;
  72.       int result;
  73.     } reply;
  74.   extern int _hurdsig_fault_exc_server (mach_msg_header_t *,
  75.                     mach_msg_header_t *);
  76.  
  77.  /* Wait for the exception_raise message forwarded by the proc server.  */
  78.  
  79.  if (__mach_msg (&request.head, MACH_RCV_MSG, 0,
  80.           sizeof request, forward_sigexc,
  81.           MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL)
  82.       != MACH_MSG_SUCCESS)
  83.     __libc_fatal ("msg receive failed on signal thread exc\n");
  84.  
  85.   /* Run the exc demuxer which should call the server function above.
  86.      That function returns 0 if the exception was expected.  */
  87.   switch (_hurdsig_fault_exc_server (&request.head, &reply.head))
  88.     {
  89.     case KERN_SUCCESS:
  90.       if (reply.head.msgh_remote_port != MACH_PORT_NULL)
  91.     __mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
  92.             0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
  93.       break;
  94.     default:
  95.       __mach_msg_destroy (&request.head);
  96.     case MIG_NO_REPLY:
  97.     }
  98.  
  99.   _hurdsig_fault_expect_signo = 0;
  100.   longjmp (_hurdsig_fault_env, 1);
  101. }
  102.  
  103. static char faultstack[1024];
  104.  
  105. /* Send exceptions for the signal thread to the proc server.
  106.    It will forward the message on to our message port,
  107.    and then restore the thread's state to code which
  108.    does `longjmp (_hurd_sigthread_fault_env, 1)'.  */
  109.  
  110. void
  111. _hurdsig_fault_init (void)
  112. {
  113.   error_t err;
  114.   struct machine_thread_state state;
  115.   mach_port_t sigexc;
  116.  
  117.   if (err = __mach_port_allocate (__mach_task_self (),
  118.                   MACH_PORT_RIGHT_RECEIVE, &sigexc))
  119.     __libc_fatal ("hurd: Can't create receive right for signal thread exc\n");
  120.   if (err = __mach_port_allocate (__mach_task_self (),
  121.                   MACH_PORT_RIGHT_RECEIVE, &forward_sigexc))
  122.     __libc_fatal ("hurd: Can't create receive right for signal thread exc\n");
  123.  
  124.   memset (&state, 0, sizeof state);
  125.   MACHINE_THREAD_STATE_SET_PC (&state, faulted);
  126.   MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);
  127.  
  128. #if 0                /* Don't confuse gdb.  */
  129.   __thread_set_special_port (_hurd_msgport_thread,
  130.                  THREAD_EXCEPTION_PORT, sigexc);
  131. #endif
  132.  
  133.   if (err = __USEPORT
  134.       (PROC,
  135.        __proc_handle_exceptions (port,
  136.                  sigexc,
  137.                  forward_sigexc, MACH_MSG_TYPE_MAKE_SEND,
  138.                  MACHINE_THREAD_STATE_FLAVOR,
  139.                  (int *) &state, MACHINE_THREAD_STATE_COUNT)))
  140.     __libc_fatal ("hurd: proc won't handle signal thread exceptions\n");
  141. }
  142.  
  143.